﻿/***********************************************************************************\
| Copyright (c) 2011, Bashar Al-Rawi                                                |
| All rights reserved.                                                              |
|                                                                                   |
| Redistribution and use in source and binary forms, with or without                |
| modification, are permitted provided that the following conditions are met:       |
|    * Redistributions of source code must retain the above copyright               |
|      notice, this list of conditions and the following disclaimer.                |
|    * Redistributions in binary form must reproduce the above copyright            |
|      notice, this list of conditions and the following disclaimer in the          |
|      documentation and/or other materials provided with the distribution.         |
|    * Neither the name of the <organization> nor the                               |
|      names of its contributors may be used to endorse or promote products         |
|      derived from this software without specific prior written permission.        |
|                                                                                   |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   |
| ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     |
| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            |
| DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY                |
| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES        |
| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      |
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND       |
| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT        |
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     |
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      |
\***********************************************************************************/

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
using System.Xml.Serialization;
using System.Xml;
using System.Diagnostics;
namespace Arabic.Utils
{
    public class SuperString
    {
        private List<Character> chars;

        static SuperString()
        {
            Character.Initialize();
        }

        public SuperString()
        {
            chars = new List<Character>();
        }

        public SuperString(string st): this()
        {
            foreach (char ch in st)
            {
                Add(ch);
            }
        }

        public static implicit operator string(SuperString t)
        {
            return t.Text;
        }

        public static implicit operator SuperString(string st)
        {
            return new SuperString(st);
        }

        public void Add(char ch)
        {
            if (ch == Character.BACKSPACE)
            {
                if (chars.Count > 0)
                {
                    if (chars.Count > 1)
                    {
                        chars[chars.Count - 2].Next = null;
                    }
                    chars.RemoveAt(chars.Count - 1);
                }
            }
            else
            {
                Character newChar = Character.CreateCharacter(ch);
                if (chars.Count > 0)
                {
                    Character prev = chars[chars.Count - 1];
                    prev.Next = newChar;
                    newChar.Prev = prev;
                }
                chars.Add(newChar);
            }
        }

        internal void FixString()
        {
            for (int i = 0; i < chars.Count; i++)
            {
                if (i < chars.Count - 1)
                {
                    chars[i].Next = chars[i + 1];
                }
                if (i > 0)
                {
                    chars[i].Prev = chars[i - 1];
                }
                Debug.WriteLine(chars[i]);
            }
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            int i = 0;
            while (i < chars.Count)
            {
                if (chars[i].Lang == KeyCode.AR)
                {
                    sb.Append(chars[i].DisplayChar);
                    i++;
                }
                else
                {
                    // English characters are appended the other way around
                    AppendEnglishChars(chars, ref i, sb);
                }

            }

            return sb.ToString();
        }

        private void AppendEnglishChars(List<Character> chars, ref int i, StringBuilder sb)
        {
            int endIdx = i;
            while (endIdx < chars.Count && chars[endIdx].Lang == KeyCode.EN)
            {
                endIdx++;
            }

            IList<Character> englishText = chars.GetRange(i, endIdx - i);

            for (int j = englishText.Count - 1; j >= 0; j--)
            {
                sb.Append(englishText[j].DisplayChar);
            }
            i = endIdx;

        }

        // this is the connected text
        public string DisplayText
        {
            get
            {
                StringBuilder sb = new StringBuilder(chars.Count);
                foreach (Character ch in chars)
                    sb.Append(ch.DisplayChar);

                return sb.ToString();
            }
        }

        // this is the original text
        public string Text
        {
            get
            {
                StringBuilder sb = new StringBuilder();
                foreach (Character ch in chars)
                {
                    sb.Append(ch.Char);
                }
                return sb.ToString();
            }
        }
    }
}
